package com.lvmama.rhino.repositories.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import com.lvmama.rhino.entity.PieRobot;
import com.lvmama.rhino.mongo.RhinoRound;
import com.lvmama.rhino.mongo.RhinoTalk;
import com.lvmama.rhino.repositories.RhinoRepository;


/**
 * 说明：
 * @author yecan
 * @date 2016年8月24日
 */
public class RhinoRespositoryImpl implements RhinoRepository {

	@Autowired
	private MongoTemplate mongoTemplate;
	@Override
	public List<RhinoRound> queryByPage(final Integer page,final Integer pageSize) {
		Query query=new Query();
		Pageable pageable=new Pageable() {
			
			@Override
			public Sort getSort() {
				return null;
			}

			@Override
			public Pageable next() {
				return null;
			}

			@Override
			public Pageable previousOrFirst() {
				return null;
			}

			@Override
			public Pageable first() {
				return null;
			}

			@Override
			public boolean hasPrevious() {
				return false;
			}

			@Override
			public int getPageSize() {
				return pageSize;
			}
			
			@Override
			public int getPageNumber() {
				return page;
			}
			
			@Override
			public int getOffset() {
				return (getPageNumber() - 1) * getPageSize();
			}
		};
		query.with(pageable);
		List<RhinoRound> find = mongoTemplate.find(query, RhinoRound.class);
		return find;
	}
	
	@Override
	public Long queryCount() {
		 Query query=new Query();
		 long count = mongoTemplate.count(query, RhinoRound.class);
		 return count;
	}

	@Override
	public List<RhinoRound> ajaxByPage(final Integer page, Date startTime,
			Date endTime, String isMatch,String source) {
		Criteria criteria=new Criteria();
		if("all".equals(source)){
		if(StringUtils.isNotBlank(isMatch)&&startTime!=null && endTime!=null){
			criteria.andOperator(Criteria.where("status").is(isMatch),Criteria.where("createTime").gte(startTime),Criteria.where("createTime").lte(endTime));
		}
		if(StringUtils.isNotBlank(isMatch)&&startTime==null && endTime==null){
			criteria.andOperator(Criteria.where("status").is(isMatch));
		}
		if(StringUtils.isBlank(isMatch)&&startTime!=null && endTime!=null){
			criteria.andOperator(Criteria.where("createTime").lte(endTime),Criteria.where("createTime").gte(startTime));
		}
		}else{

			if(StringUtils.isNotBlank(isMatch)&&startTime!=null && endTime!=null){
				criteria.andOperator(Criteria.where("status").is(isMatch),Criteria.where("createTime").gte(startTime),Criteria.where("createTime").lte(endTime),Criteria.where("source").is(source));
			}
			if(StringUtils.isNotBlank(isMatch)&&startTime==null && endTime==null){
				criteria.andOperator(Criteria.where("status").is(isMatch),Criteria.where("source").is(source));
			}
			if(StringUtils.isBlank(isMatch)&&startTime!=null && endTime!=null){
				criteria.andOperator(Criteria.where("createTime").lte(endTime),Criteria.where("createTime").gte(startTime),Criteria.where("source").is(source));
			}
			
		}
		Query query=new Query(criteria);
		
		Pageable pageable=new Pageable() {
			
			@Override
			public Sort getSort() {
				return new Sort(Direction.DESC, "createTime");
			}

			@Override
			public Pageable next() {
				return null;
			}

			@Override
			public Pageable previousOrFirst() {
				return null;
			}

			@Override
			public Pageable first() {
				return null;
			}

			@Override
			public boolean hasPrevious() {
				return false;
			}

			@Override
			public int getPageSize() {
				return 8;
			}
			
			@Override
			public int getPageNumber() {
				return page;
			}
			
			@Override
			public int getOffset() {
				return (getPageNumber() - 1) * getPageSize();
			}
		};
		query.with(pageable);
		List<RhinoRound> find = mongoTemplate.find(query, RhinoRound.class);
		return find;
	}

	@Override
	public Long queryAjaxCount(Date startTime, Date endTime, String isMatch,String source) {
		Criteria criteria=new Criteria();
		if("all".equals(source)){
		if(StringUtils.isNotBlank(isMatch)&&startTime!=null && endTime!=null){
			criteria.andOperator(Criteria.where("status").is(isMatch),Criteria.where("createTime").gte(startTime),Criteria.where("createTime").lte(endTime));
		}
		if(StringUtils.isNotBlank(isMatch)&&startTime==null && endTime==null){
			criteria.andOperator(Criteria.where("status").is(isMatch));
		}
		if(StringUtils.isBlank(isMatch)&&startTime!=null && endTime!=null){
			criteria.andOperator(Criteria.where("createTime").lte(endTime),Criteria.where("createTime").gte(startTime));
		}
		}else{

			if(StringUtils.isNotBlank(isMatch)&&startTime!=null && endTime!=null){
				criteria.andOperator(Criteria.where("status").is(isMatch),Criteria.where("createTime").gte(startTime),Criteria.where("createTime").lte(endTime),Criteria.where("source").is(source));
			}
			if(StringUtils.isNotBlank(isMatch)&&startTime==null && endTime==null){
				criteria.andOperator(Criteria.where("status").is(isMatch),Criteria.where("source").is(source));
			}
			if(StringUtils.isBlank(isMatch)&&startTime!=null && endTime!=null){
				criteria.andOperator(Criteria.where("createTime").lte(endTime),Criteria.where("createTime").gte(startTime),Criteria.where("source").is(source));
			}
			
		}
		Query query=new Query(criteria);
		 long count = mongoTemplate.count(query, RhinoRound.class);
		return count;
	}

	
	@Override
	public List<PieRobot> ajaxPie(Date startDate, Date endDate) {
				long count1 = getCount(startDate, endDate,"status","source","MATCH", "eai",RhinoRound.class);
				PieRobot p1=new PieRobot();
				p1.setName("命中(eai)");
				p1.setValue((int)count1);

				long count2 = getCount(startDate, endDate,"status","source", "MATCH", "es",RhinoRound.class);
				PieRobot p2=new PieRobot();
				p2.setName("命中(es)");
				p2.setValue((int)count2);

				long count3 = getCount(startDate, endDate,"status","source", "MATCH", "turing",RhinoRound.class);
				PieRobot p3=new PieRobot();
				p3.setName("命中(turing)");
				p3.setValue((int)count3);

				long count4 = getCount(startDate, endDate,"status","source", "MATCH", "self",RhinoRound.class);
				PieRobot p4=new PieRobot();
				p4.setName("命中(self)");
				p4.setValue((int)count4);

				long count5 = getCount(startDate, endDate,"status","source", "NOT_MATCH", "eai",RhinoRound.class);
				PieRobot p5=new PieRobot();
				p5.setName("未命中(eai)");
				p5.setValue((int)count5);

				long count6 = getCount(startDate, endDate,"status","source", "NOT_MATCH", "es",RhinoRound.class);
				PieRobot p6=new PieRobot();
				p6.setName("未命中(es)");
				p6.setValue((int)count6);

				long count7 = getCount(startDate, endDate,"status","source", "NOT_MATCH", "turing",RhinoRound.class);
				PieRobot p7=new PieRobot();
				p7.setName("未命中(turing)");
				p7.setValue((int)count7);

				long count8 = getCount(startDate, endDate,"status","source", "NOT_MATCH", "self",RhinoRound.class);
				PieRobot p8=new PieRobot();
				p8.setName("未命中(self)");
				p8.setValue((int)count8);

				long count9 = getCount(startDate, endDate,"status","source", "EXCEPTION", "eai",RhinoRound.class);
				PieRobot p9=new PieRobot();
				p9.setName("异常(eai)");
				p9.setValue((int)count9);

				long count10 = getCount(startDate, endDate,"status","source", "EXCEPTION", "es",RhinoRound.class);
				PieRobot p10=new PieRobot();
				p10.setName("异常(es)");
				p10.setValue((int)count10);

				long count11 = getCount(startDate, endDate,"status","source", "EXCEPTION", "turing",RhinoRound.class);
				PieRobot p11=new PieRobot();
				p11.setName("异常(turing)");
				p11.setValue((int)count11);

				long count12 = getCount(startDate, endDate, "status","source","EXCEPTION", "self",RhinoRound.class);
				PieRobot p12=new PieRobot();
				p12.setName("异常(self)");
				p12.setValue((int)count12);

				 List<PieRobot> list=new ArrayList<>();
				 list.add(p1);
				 list.add(p2);
				 list.add(p3);
				 list.add(p4);
				 list.add(p5);
				 list.add(p6);
				 list.add(p7);
				 list.add(p8);
				 list.add(p9);
				 list.add(p10);
				 list.add(p11);
				 list.add(p12);
				 return list;
	}

	@Override
	public List<RhinoRound> exportMongoData(String isMatch, Date startDate,
			Date endDate,String source) {
		Criteria criteria=new Criteria();
		if("all".equals(source)){
		if(StringUtils.isNotBlank(isMatch)&&startDate!=null && endDate!=null){
			criteria.andOperator(Criteria.where("status").is(isMatch),Criteria.where("createTime").gte(startDate),Criteria.where("createTime").lte(endDate));
		}
		if(StringUtils.isNotBlank(isMatch)&&startDate==null && endDate==null){
			criteria.andOperator(Criteria.where("status").is(isMatch));
		}
		if(StringUtils.isBlank(isMatch)&&startDate!=null && endDate!=null){
			criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate));
		}
		}else{

			if(StringUtils.isNotBlank(isMatch)&&startDate!=null && endDate!=null){
				criteria.andOperator(Criteria.where("status").is(isMatch),Criteria.where("createTime").gte(startDate),Criteria.where("createTime").lte(endDate),Criteria.where("source").is(source));
			}
			if(StringUtils.isNotBlank(isMatch)&&startDate==null && endDate==null){
				criteria.andOperator(Criteria.where("status").is(isMatch),Criteria.where("source").is(source));
			}
			if(StringUtils.isBlank(isMatch)&&startDate!=null && endDate!=null){
				criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate),Criteria.where("source").is(source));
			}
			
		}
		Query query=new Query(criteria);
		List<RhinoRound> find = mongoTemplate.find(query, RhinoRound.class);
		return find;
	}

	
	@Override
	public List<RhinoTalk> findSatisfactionData(String satisfaction,final String page,Date startDate,
			Date endDate,String source) {
			Criteria criteria=new Criteria();
			if("all".equals(source)){
			if(startDate!=null && endDate!=null && StringUtils.isBlank(satisfaction)){
				criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate));
			}
			if(startDate!=null && endDate!=null && StringUtils.isNotBlank(satisfaction)){
				criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate),Criteria.where("satisfaction").is(satisfaction));
			}
			if(startDate==null && endDate==null && StringUtils.isNotBlank(satisfaction)){
				criteria.andOperator(Criteria.where("satisfaction").is(satisfaction));
			}
			}else{

				if(startDate!=null && endDate!=null && StringUtils.isBlank(satisfaction)){
					criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate),Criteria.where("serviceApply").is(source));
				}
				if(startDate!=null && endDate!=null && StringUtils.isNotBlank(satisfaction)){
					criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate),Criteria.where("satisfaction").is(satisfaction),Criteria.where("serviceApply").is(source));
				}
				if(startDate==null && endDate==null && StringUtils.isNotBlank(satisfaction)){
					criteria.andOperator(Criteria.where("satisfaction").is(satisfaction),Criteria.where("serviceApply").is(source));
				}
				
			}
			
		Query query=new Query(criteria);
		Pageable pageable=new Pageable() {
			
			@Override
			public Sort getSort() {
				return new Sort(Direction.DESC, "createTime");
			}

			@Override
			public Pageable next() {
				return null;
			}

			@Override
			public Pageable previousOrFirst() {
				return null;
			}

			@Override
			public Pageable first() {
				return null;
			}

			@Override
			public boolean hasPrevious() {
				return false;
			}

			@Override
			public int getPageSize() {
				return 12;
			}
			
			@Override
			public int getPageNumber() {
				return Integer.valueOf(page);
			}
			
			@Override
			public int getOffset() {
				return (getPageNumber() - 1) * getPageSize();
			}
		};
		query.with(pageable);
		List<RhinoTalk> find = mongoTemplate.find(query, RhinoTalk.class);
		
		//用手机号替换用户id，接口那边还没有存手机号，暂时注释掉
		/*for (RhinoTalk rhinoTalk : find) {
			rhinoTalk.setMobileNumber(StringUtils.isBlank(rhinoTalk.getMobileNumber())?"匿名用户":rhinoTalk.getMobileNumber());
		}*/
		/*List<RhinoTalk> find=querySatisfactionAndSource(satisfaction, startDate, endDate, source);*/
		/*Collections.reverse(find);
		int page1=Integer.valueOf(page);
		
		List<RhinoTalk> reList=find.subList((page1-1)*12,page1*12>find.size()?find.size():page1*12);*/
		for (RhinoTalk rhinoTalk : find) {
			rhinoTalk.setUserId(StringUtils.isBlank(rhinoTalk.getUserId())?"匿名用户":rhinoTalk.getUserId());
		}
		
		for (RhinoTalk rhinoTalk : find) {
			rhinoTalk.setSatisfaction(StringUtils.isBlank(rhinoTalk.getSatisfaction())?"暂无":rhinoTalk.getSatisfaction());
		}
		return find;
	}

	
	@Override
	public Long queryTalkCount(String satisfaction,Date startDate, Date endDate,String source) {
		Criteria criteria=new Criteria();
		if("all".equals(source)){
		if(startDate!=null && endDate!=null && StringUtils.isBlank(satisfaction)){
			criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate));
		}
		if(startDate!=null && endDate!=null && StringUtils.isNotBlank(satisfaction)){
			criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate),Criteria.where("satisfaction").is(satisfaction));
		}
		if(startDate==null && endDate==null && StringUtils.isNotBlank(satisfaction)){
			criteria.andOperator(Criteria.where("satisfaction").is(satisfaction));
		}
		}else{

			if(startDate!=null && endDate!=null && StringUtils.isBlank(satisfaction)){
				criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate),Criteria.where("serviceApply").is(source));
			}
			if(startDate!=null && endDate!=null && StringUtils.isNotBlank(satisfaction)){
				criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate),Criteria.where("satisfaction").is(satisfaction),Criteria.where("serviceApply").is(source));
			}
			if(startDate==null && endDate==null && StringUtils.isNotBlank(satisfaction)){
				criteria.andOperator(Criteria.where("satisfaction").is(satisfaction),Criteria.where("serviceApply").is(source));
			}
			
		}
		Query query=new Query(criteria);
		return mongoTemplate.count(query, RhinoTalk.class);
		/*List<RhinoTalk> querySatisfactionAndSource = querySatisfactionAndSource(satisfaction, startDate, endDate, source);
		return (long)(querySatisfactionAndSource.size());*/
	}

	@Override
	public List<RhinoRound> queryBySessionId(final Integer page, String sessionId) {
		Criteria criteria=new Criteria();
		criteria.andOperator(Criteria.where("sessionId").is(sessionId));
		Query query=new Query(criteria);
		Pageable pageable=new Pageable() {
			
			@Override
			public Sort getSort() {
				return null;
			}

			@Override
			public Pageable next() {
				return null;
			}

			@Override
			public Pageable previousOrFirst() {
				return null;
			}

			@Override
			public Pageable first() {
				return null;
			}

			@Override
			public boolean hasPrevious() {
				return false;
			}

			@Override
			public int getPageSize() {
				return 3;
			}
			
			@Override
			public int getPageNumber() {
				return Integer.valueOf(page);
			}
			
			@Override
			public int getOffset() {
				return (getPageNumber() - 1) * getPageSize();
			}
		};
		query.with(pageable);
		List<RhinoRound> find = mongoTemplate.find(query,RhinoRound.class);
		return find;
	}

	
	@Override
	public Long queryCountBySessionId(String sessionId) {
		Criteria criteria=new Criteria();
		criteria.andOperator(Criteria.where("sessionId").is(sessionId));
		Query query=new Query(criteria);
		long count = mongoTemplate.count(query,RhinoRound.class);
		return count;
	}

	
	@Override
	public List<PieRobot> ajaxSatisfactionPie(Date startDate, Date endDate) {
        Criteria criteria=new Criteria();
        if(startDate!=null && endDate!=null){
            criteria.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate),Criteria.where("serviceApply").is("es"));
        }
        Query query=new Query(criteria);
        long count11 = mongoTemplate.count(query, RhinoTalk.class);

        Criteria criteria1=new Criteria();
        if(startDate!=null&&endDate!=null){
            criteria1.andOperator(Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate),Criteria.where("serviceApply").is("eai"));
        }
        Query query1=new Query(criteria1);
        long count12 = mongoTemplate.count(query1, RhinoTalk.class);

		long count1=getCount(startDate,endDate,"satisfaction","serviceApply","GOOD","eai",RhinoTalk.class);
        PieRobot p1=new PieRobot();
        p1.setName("满意(eai)");
        p1.setValue((int)count1);

        long count2=getCount(startDate,endDate,"satisfaction","serviceApply","GOOD","es",RhinoTalk.class);
        PieRobot p2=new PieRobot();
        p2.setName("满意(es)");
        p2.setValue((int)count2);

        long count3=getCount(startDate,endDate,"satisfaction","serviceApply","BAD","eai",RhinoTalk.class);
        PieRobot p3=new PieRobot();
        p3.setName("不满意(eai)");
        p3.setValue((int)count3);

        long count4=getCount(startDate,endDate,"satisfaction","serviceApply","BAD","es",RhinoTalk.class);
        PieRobot p4=new PieRobot();
        p4.setName("不满意(es)");
        p4.setValue((int)count4);

        long count5=getCount(startDate,endDate,"satisfaction","serviceApply","OK","eai",RhinoTalk.class);
        PieRobot p5=new PieRobot();
        p5.setName("一般(eai)");
        p5.setValue((int)count5);

        long count6=getCount(startDate,endDate,"satisfaction","serviceApply","OK","es",RhinoTalk.class);
        PieRobot p6=new PieRobot();
        p6.setName("一般(es)");
        p6.setValue((int)count6);

        List<PieRobot> list=new ArrayList<>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        list.add(p4);
        list.add(p5);
        list.add(p6);
        PieRobot p7=new PieRobot();
        p7.setName("暂无(es)");
        p7.setValue((int)(count11-count2-count4-count6));
        list.add(p7);

        PieRobot p8=new PieRobot();
        p8.setName("暂无(eai)");
        p8.setValue((int)(count12-count1-count3-count5));
        list.add(p8);
        return list;
	}

	@Override
	public RhinoTalk queryTalkBySessionId(String sessionId) {
		Criteria criteria=new Criteria();
		 criteria.andOperator(Criteria.where("sessionId").is(sessionId));
		 Query query=new Query(criteria);
		RhinoTalk findOne = mongoTemplate.findOne(query, RhinoTalk.class);
		return findOne;
		
	}

	private long getCount(Date startDate, Date endDate,String statusName,String sourceName,String status,String source,Class c){
		Criteria criteria=new Criteria();
		if(startDate!=null&&endDate!=null){
			criteria.andOperator(Criteria.where(statusName).is(status),Criteria.where(sourceName).is(source),Criteria.where("createTime").lte(endDate),Criteria.where("createTime").gte(startDate));
		}else{
			criteria.andOperator(Criteria.where(statusName).is(status),Criteria.where(sourceName).is(source));
		}
		Query query=new Query(criteria);
		long count = mongoTemplate.count(query,c);
		return count;
	}
}
